package br.com.poolme.connection;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import br.com.poolme.telas.Jogador;

public class PoolMEMessage implements Runnable {

    private static final byte NEW_GAME = 10;
    private static final byte ACCEPT_NEW_GAME = 20;
    private static final byte REJECT_NEW_GAME = 30;
    private static final byte MOVE = 40;
    private static final byte QUIT_GAME = 50;
    private DataInputStream input;
    private DataOutputStream output;
    private MessageListener messageListener;
    private boolean stop;

    public PoolMEMessage(DataInputStream input, DataOutputStream output,
            MessageListener listener) {
        messageListener = listener;
        this.input = input;
        this.output = output;
        stop = false;
        Thread receiverThread = new Thread(this, "Receptor");
        receiverThread.start();
    }

    public void sendNewGame(Jogador jogador) {
        try {
            output.writeByte(NEW_GAME);
            output.writeUTF(jogador.getName() + jogador.getMarkType());
            output.flush();
        } catch (IOException e) {
            messageListener.connectionError(e);
        }
    }

    public void sendAcceptNewGame(byte firstPlayer) {
        try {
            output.writeByte(ACCEPT_NEW_GAME);
            output.writeByte(firstPlayer);
            output.flush();
        } catch (IOException e) {
            messageListener.connectionError(e);
        }
    }

    public void sendRejectNewGame() {
        try {
            output.writeByte(REJECT_NEW_GAME);
            output.flush();
        } catch (IOException e) {
            messageListener.connectionError(e);
        }
    }

    public void sendMove(byte position) {
        try {
            output.writeByte(MOVE);
            output.writeByte(position);
            output.flush();
        } catch (IOException e) {
            messageListener.connectionError(e);
        }
    }

    public void sendQuitGame() {
        try {
            output.writeByte(QUIT_GAME);
            output.flush();
        } catch (IOException e) {
            messageListener.connectionError(e);
        }
    }

    public void run() {
        while (!stop) {
            try {
                byte msgType = input.readByte();
                switch (msgType) {
                case NEW_GAME:
                    String playerString = input.readUTF();
                    Jogador opponent = createPlayer(playerString);
                    messageListener.newGameReceived(opponent);
                    break;
                case ACCEPT_NEW_GAME:
                    byte firstPlayer = input.readByte();
                    messageListener.acceptNewGameReceived(firstPlayer);
                    break;
                case REJECT_NEW_GAME:
                    messageListener.rejectNewGameReceived();
                    break;
                case MOVE:
                    byte position = input.readByte();
                    messageListener.moveReceived(position);
                    break;
                case QUIT_GAME:
                    messageListener.quitGameReceived();
                    break;
                }
            } catch (IOException e) {
            }
        }
    }

    private Jogador createPlayer(String str) {
        Jogador p = new Jogador(str.substring(0, str.length() - 1));
        char mark = str.charAt(str.length() - 1);
        if (mark == Jogador.X) {
            p.setXMark();
        } else if (mark == Jogador.O) {
            p.setOMark();
        }
        return p;
    }

    public void stop() {
        stop = true;
        try {
            input.close();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}